#include <vector>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;

int main(){
	vector<string> tokens; 
	vector<vector<string>> result;
	vector<string> result_component;
	string str = "stmt s , s1, s2 ,s3;while w1,w2,w3;Select whatever";
	string strSynonym;
	string chopped_string;
	size_t found;

	//initial dissection of synonym declaration
	size_t found_last_semicolon;
	found_last_semicolon = str.find_last_of(";");
	if(found_last_semicolon != std::string::npos){
		strSynonym = str.substr(0, found_last_semicolon+1); //cut the string into just synonym declaration, including the last semicolon
		str = str.substr(found_last_semicolon+1, str.length()); //and the rest of the string consist of Select statements and whatnot
		while(true){
			found = strSynonym.find(";");
			if(found != std::string::npos){
				chopped_string = strSynonym.substr(0, found);	//chop the string until the first instance of semicolon, and remove the semicolon
				strSynonym = strSynonym.substr(found+1, strSynonym.length()-(found+1)); //get the rest of the string after the first semicolon
				
				string temp_string = chopped_string;
				istringstream iss(temp_string); 
				tokens.clear();
				while(iss >> temp_string){ 
					tokens.push_back(temp_string);
				}
				
				//synonym declaration check
				if(tokens.at(0) == "stmt" || tokens.at(0) == "while"){
					string component = tokens.at(0);
					result_component.push_back(component);
					//tokens.erase(tokens.begin());
					//get rid of the synonym type declaration
					chopped_string = chopped_string.substr(component.length(), chopped_string.length()); //now becomes " s , s1, s2 ,s3" or remove the synonym type declaration
					
					//get the synonyms by finding commas if any
					size_t comma;
					comma = chopped_string.find(",");
					if(comma != std::string::npos){ //find first occurence of ","
						while(true){
							string syn = chopped_string.substr(0, comma);
							
							size_t first_non_whitespace;
							size_t last_non_whitespace;
							size_t range;
							
							first_non_whitespace = syn.find_first_not_of(" ");
							if(first_non_whitespace == std::string::npos){//this is the check if "stmt ," before going through line 33 and 41
								cout << "syntax error no synonym before comma" << endl;
							}
							last_non_whitespace = syn.find_last_not_of(" ");
							range = last_non_whitespace - first_non_whitespace + 1;
							
							syn = syn.substr(first_non_whitespace, range); 
							result_component.push_back(syn);
							chopped_string = chopped_string.substr(comma+1, chopped_string.length()-(comma+1));
							
							//search for more commas
							comma = chopped_string.find(",");
							if(comma == std::string::npos){
								first_non_whitespace = chopped_string.find_first_not_of(" ");
								if(first_non_whitespace == std::string::npos){
									cout << "error, nothing after comma" << endl;
								}
								else{
									last_non_whitespace = chopped_string.find_last_not_of(" ");
									range = last_non_whitespace - first_non_whitespace + 1;
									result_component.push_back(chopped_string.substr(first_non_whitespace, range));
									
								}
								break;
							}
						}
					}
					else{ //stmt ;
						if(tokens.size() != 0){
							result_component.push_back(tokens.at(0)); //for example "stmt s" (semicolon is already removed from step above). 
																		//After erasing "stmt", left with "s"
						}
						else{
							cout << "no synonym declared" << endl;
							
						}
						break;
					}
					
					result.push_back(result_component); 
					result_component.clear();
				}
				else{
					cout << "syntax error no synonym type declaration" << endl;
					break;
				}
			}
			else{ //no more semicolon then break
				break;
			}
		}
	}
	else{
		cout << "syntax error, semicolon missing" << endl;
	}
	
	
	for(int i=0;i<result.size();i++){
		for(int j=0;j<result.at(i).size();j++){
			cout << result.at(i).at(j) << " ";
		}
		cout << endl;
	}
	//cout << found << endl;
	//cout << testing.front() << endl;

return 0;
}